package com.xiang.api.controller;

import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

import com.alibaba.fastjson2.JSONObject;
import com.xiang.api.Util;
import com.xiang.api.entity.Message;
import com.xiang.api.service.ReadFile;
import com.xiang.api.service.Upload;
import com.xiang.api.service.WxService;
import com.xiang.sql.StaticService;
import com.xiang.sql.StaticSql;
import com.xiang.sql.entity.User;
import com.xiang.sql.service.UploadService;
import com.xiang.sql.service.UserService;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.view.RedirectView;

@RestController
public class IndexController {
  @Autowired
  ReadFile readFile;

  @Autowired
  UploadService uploadService;

  @GetMapping("/file/{id:.+}")
  public void file(@PathVariable("id") String id, HttpServletRequest request, HttpServletResponse response) {
    uploadService.read(id, request, response);
  }

  @GetMapping("/**")
  public void index(HttpServletRequest request, HttpServletResponse response) throws Exception {
    readFile.index(request, response);
  }

  /** API 跳转 */
  @GetMapping("/mp")
  public Object mp(@RequestParam(value = "path", required = false) String path) {
    return new RedirectView(wxService.getMpLink(path));
  }

  /** 微信强制跳转 */
  @GetMapping("/mp/pages/jmp")
  public Object mpPagesJmp(@RequestParam(value = "path", required = false) String path) {
    return new RedirectView(wxService.getMpLink(path));
  }

  private void wqr(String txt, HttpServletResponse response) {
    System.out.println(txt);
    try {
      response.addHeader("Access-Control-Expose-Headers", "Content-Disposition");
      response.setHeader("content-type", "image/png");
      byte[] b = Util.qr(txt);
      response.getOutputStream().write(b);
      response.flushBuffer();
    } catch (Exception e) {
      // e.printStackTrace();
      try {
        response.sendError(404);
        response.getWriter().close();
      } catch (Exception _e) {
      }
    }
  }

  /** 推荐码 */
  @GetMapping("/tjm/{id:.+}")
  public void tjm(@PathVariable("id") String id, HttpServletResponse response) {
    int live = StaticSql.service.group.getMerchantUserLiveByID(id);
    String url = null;
    if (live > 0) {
      url = String.format("https://%s/mp/pages/jmp?path=/pages/index?%sgid=%s",
          StaticSql.service.setting.getValueById("domain"), live > 3 ? "" : "cg=1&", id);
    }
    wqr(url, response);
  }

  /** 店铺码 */
  @GetMapping("/dpm/{id:.+}")
  public void dpm(@PathVariable("id") String id, HttpServletResponse response) {
    int live = StaticSql.service.group.getMerchantUserLiveByID(id);
    String url = null;
    if (live > 0) {
      url = String.format("https://%s/mp/pages/jmp?path=/pages/index?gid=%s",
          StaticSql.service.setting.getValueById("domain"), id);
    }
    wqr(url, response);
  }

  /** 兑奖 */
  @GetMapping("/prize/{id:.+}")
  public void prize(@PathVariable("id") String id, HttpServletResponse response) {
    String url = String.format("https://%s/mp/pages/jmp?path=/pages/cash?id=%s",
        StaticSql.service.setting.getValueById("domain"), id);
    wqr(url, response);
  }

  @GetMapping("/goods/read")
  public Object goodsRead() {
    return StaticSql.service.goods.ylq();
  }

  @Autowired
  UserService userService;

  @PostMapping("/login")
  public Object login(HttpServletRequest request) {
    return Message.success("登录成功", userService.getToken(Util.request2json(request)));
  }

  @PostMapping("/reg")
  public Object reg(HttpServletRequest request) {
    return userService.getToken(userService.create(Util.request2json(request), null));
  }

  @Autowired
  Upload upload;

  @PostMapping("/upload")
  public Object upload(HttpServletRequest request) {
    return upload.index(request);
  }

  @Autowired
  WxService wxService;

  @PostMapping("/wxlogin")
  public Object wxlogin(HttpServletRequest request) {
    return wxService.login(Util.request2json(request));
  }

  @PostMapping("/wxpay")
  public Object wxpay(HttpServletRequest request) {
    User user = userService.getByToken(request.getHeader("token"));
    return StaticSql.service.order.wxpay(Util.request2json(request), user);
    // JSONObject a = StaticSql.service.order
    // .wxpay(Util.request2json(request), user),
    // b = a.clone();
    // b.put("data", a);
    // return b;
  }

  @PostMapping("/notifyjsapi")
  public Object notifyJsapi(HttpServletRequest request) {
    return wxService.notifyJsapi(request);
  }

  private Object runMethod(String tableName, String methodName, JSONObject p, User per) {
    String s = "tableName 错误";
    try {
      Field field = StaticSql.service.class.getField(tableName);
      if (field != null) {
        s = "内部错误";
        Object mif = field.get(null);
        if (mif != null) {
          s = "没有此方法";
          Method method = mif.getClass().getMethod(methodName, JSONObject.class, User.class);
          if (method != null) {
            return method.invoke(mif, p, per);
          }
        }
      }
    } catch (Exception e) {
      s = Util.errString(e);
      System.out.println("runMethod执行方法错误:" + s);
    }
    return new Message(s);
  }

  @PostMapping("/{tableName}/{methodName}")
  public Object tableMethod(@PathVariable String tableName, @PathVariable String methodName,
      HttpServletRequest request) {
    User u = null;
    if (!(tableName.equals("goods") && methodName.equals("read"))) {
      u = userService.getByToken(request.getHeader("token"));
    }
    return runMethod(tableName, methodName, Util.request2json(request), u);
  }

  @PostMapping("/{type}")
  public Object type(@PathVariable String type, HttpServletRequest request) throws Exception {
    Method method = null;
    String tableName = null, methodName = null;
    Object mif = this;
    List<String> ts = Util.splitByUpperCase(type);
    int tl = ts.size(), size = tl;
    while (--tl > 0) {
      methodName = Util.FristLower(String.join("", ts.subList(tl, size)));
      tableName = Util.FristLower(String.join("", ts.subList(0, tl)));
      try {
        Field field = StaticService.class.getField(tableName);
        mif = field.get(null);
        if (mif != null) {
          method = mif.getClass().getMethod(methodName, JSONObject.class, User.class);
          break;
        }
      } catch (Exception e) {
        method = null;
        break;
      }
    }
    if (method != null && mif != null && tableName != null && methodName != null) {
      User user = null;
      if (!(tableName.equals("goods") && methodName.equals("read"))) {
        user = userService.getByToken(request.getHeader("token"));
      }
      return method.invoke(mif, Util.request2json(request), user);
    }
    return new Message("路径错误:" + type);
  }

  @GetMapping("/tst/{id:.+}")
  public Object tst(@PathVariable("id") String id) {
    return "完成2:" + id;
  }

}
